﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;



// 1.求最小公倍数
#include <iostream>
using namespace std;
int gcd(int a, int b)
{
	if (b == 0) return a;
	return gcd(b, a % b);
}
int main()
{
	int a, b;
	cin >> a >> b;
	cout << (a * b / gcd(a, b)) << endl;
	return 0;
}

// 2.数组中的最⻓连续⼦序列
class Solution {
public:
	int MLS(vector<int>& arr) {
		if (arr.size() == 1)
			return 1;
		sort(arr.begin(), arr.end());

		int len = 0;
		int l = 0, r = 1;
		int cnt = 1;
		while (true)
		{
			if (arr[r] == arr[l] + cnt)
			{
				cnt++;
				r++;
			}
			else if (arr[r] == arr[l] + cnt - 1)
			{
				r++;
			}
			else
			{
				cnt = 1;
				len = max(len, arr[r - 1] - arr[l] + 1);
				l = r;
				r++;
			}
			if (r == arr.size())
			{
				len = max(len, arr[r - 1] - arr[l] + 1);
				break;
			}
		}
		return len;
	}
};

// 3.字母收集
#include <iostream>
using namespace std;

const int N = 520;
int dp[N][N];
char mp[N][N];
int n, m;

int main() {
	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			cin >> mp[i][j];
		}
	}

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
			if (mp[i][j] == 'l')
				dp[i][j] += 4;
			if (mp[i][j] == 'o')
				dp[i][j] += 3;
			if (mp[i][j] == 'v')
				dp[i][j] += 2;
			if (mp[i][j] == 'e')
				dp[i][j] += 1;
		}
	}
	cout << dp[n][m] << endl;

	return 0;
}